home *** CD-ROM | disk | FTP | other *** search
- <<< trsdata.mac >>>
- subttl data segment
- dseg
- ;
- ; state symbols
- ;
- _a equ 1 ;abort
- _c equ 2 ;complete
- _r equ 3 ;receive init
- _rf equ 4 ;receive file header
- _rd equ 5 ;receive data
- _s equ 6 ;send init
- _sf equ 7 ;send file header
- _sd equ 8 ;send data
- _se equ 9 ;send end-of-file
- _sb equ 10 ;send break transmission
- _o equ 11 ;open file (pre send init)
- _end equ 255
- ;
- public fcb,filbuf,recptr,recbuf,paraml,lrecl
- public create,byte,word,screen,rftab,rdtab
- public slen,spaket,rlen,rpaket,sinit
- public rinit,port,baud,wdlen,baudtb,lab,parsetb
- public parity,stop,oldstk,scrtch,cmdlin,high
- public state,n,r,init,ssvc,rsvc,csvc,altsvc
- public nsvc,stack,stjump,rtype
- extrn abort,exit,r_init,r_file,r_data
- extrn rf_f,rf_b,rf_x,rd_d,rd_z
- extrn s_open,s_file,s_data,s_eof,s_break,s_init
- public filnam,crp,cbp,work
- extrn eof,sets,setr,setb,setf,setp,setc,setw,seter
- extrn setl
- ;
- ; fcb and others file related matters
- ;
- filnam: ds 30 ;will hold filename for send
- fcb: ds 60 ;file control block
- filbuf: ds 512 ;file buffer
- crp:
- recptr: db 0 ;
- recbuf: ds 256 ;record buffer
- paraml: dw filbuf ;parameter list for file svc's
- dw recbuf
- dw eof ;send end of file routine
- db 'W' ;read/write
- lrecl: db 1 ;default is 1
- db 'F' ;always fixed record length
- create: db 2 ;default is create
- db 0 ;user attrib = 0
- ;
- ; packet buffers
- ;
- cbp:
- slen: db 0 ;send buffer length (all included)
- spaket: ds 100 ;send packet
- rlen: db 0 ;receive buffer length
- rpaket: dw 0 ;receive packet store
- rtype: ds 100 ;here is where we store type
- ;
- ; the send init exchange
- ;
- sinit: db 13 ;will contain the send init received
- db 13,13,13,13,13,13,13,13,13,13,13
- maxlen equ 94 ;maximum packet length
- tout equ 10 ;time out
- quote equ '#'
- cr equ 13 ;carriage return (eol)
- rinit: ;the send-init we will send
- db maxlen+32
- db tout+32
- db 0+32
- db 64
- db cr+32 ;eol
- db quote
- db 'N'
- db '1'
- db ' '
- db 32
- ; telecomm buffers
- ;
- port: db 'A' ;default is A
- baud: db 8 ;baud rate (9600)
- wdlen: db 8 ;8 bits' byte
- parity: db 'N' ;none
- stop: db 1
- db 0 ;end
- ;
- ; misc
- ;
- oldstk: dw 0 ;save stack here on entry
- scrtch: dw 0 ;last+1 byte of pgm on entry
- cmdlin: dw 0 ;address of command line
- byte: db 0 ;scratch byte
- word: dw 0 ;scratch word
- work: ;work space for parser
- db '0','0','0','0','0'
- screen: db 0 ;flag for typing on screen
- ;
- high: dw 0 ;high memory
- state: db 3 ;current state of automaton
- n: db 0 ;current packet number
- r: db 0 ;current retry count
- init: db 0 ;do comm init on entry if != 0
- ;
- ; svc for comm operations
- ;
- ssvc: db 97 ;send on channel A
- rsvc: db 96 ;receive on channel A
- csvc: db 100 ;control on channel A
- altsvc: db 0,99,98,101 ;same for channel B
- nsvc: db 4 ;number of bytes to move
- ;
- ; stack
- ;
- ds 400 ;lots of space
- stack:
- stjump: db _a ;main jump table
- dw abort
- db _c
- dw exit
- db _r
- dw r_init
- db _rf
- dw r_file
- db _rd
- dw r_data
- db _o
- dw s_open
- db _s
- dw s_init
- db _sf
- dw s_file
- db _sd
- dw s_data
- db _se
- dw s_eof
- db _sb
- dw s_break
- db _end ;end of table
-
- rftab: db _a
- dw abort
- db 'F'
- dw rf_f
- db 'B'
- dw rf_b
- db 'X'
- dw rf_x
- db _end
-
- rdtab: db _a
- dw abort
- db 'D'
- dw rd_d
- db 'Z'
- dw rd_z
- db _end
- ;
- baudtb:
- db '110 ',1
- db '150 ',2
- db '300 ',3
- db '600 ',4
- db '1200',5
- db '2400',6
- db '4800',7
- db '9600',8
- db 13 ;end of table
- lab:
- dw l1,l2,0
- l1:
- db 3,'{}',13
- l2:
- db 1,'/'
- parsetb:
- db 0
- dw seter
- db 'W'
- dw setw
- db 'S'
- dw sets
- db 'R'
- dw setr
- db 'F'
- dw setf
- db 'P'
- dw setp
- db 'B'
- dw setb
- db 'C'
- dw setc
- db 'L'
- dw setl
- db _end
- end
- <<< trsmain.mac >>>
- subttl kmain/mac main parser and initialization routin
- cseg
- extrn oldstk,scrtch,high,cmdlin,stack,stjump,lab
- extrn rftab,rdtab,rtype,abort,parity,port,fcb,baud
- extrn wdlen,baudtb,parsetb,byte,initcm,init,state
- public mjump,rdjump,rfjump,sets,setr,setf,setb,setp,setc
- public setw,seter,setl
- extrn lrecl,filnam,paraml,work
- ;
- ; macros
- ;
- ; prmes to display a message stored by mssg
- ; call prmes lab
- ;
- prmes macro lab
- .xlist
- extrn m_&lab,l_&lab
- push hl
- push bc
- ld hl,m_&lab
- ld bc,(l_&lab)
- ld c,13
- ld a,9
- rst 8
- pop bc
- pop hl
- .list
- endm
- ;
- ; jumptb jump according to a jump table
- ; call jumptb table,code
- ; where table is the address of the table
- ; and code is a one-byte code
- ;
- jumptb macro table,code
- .xlist
- local $1
- ld hl,table
- ld bc,(code)
- ld b,c
- ld a,28 ;lookup call
- rst 8 ;dos
- jr z,$1 ;no error
- ld hl,table+1 ;get abort address (first entry)
- $1:
- jp (hl)
- .list
- endm
- ;
- ; main entry save usefull registers
- ;
- start:
- ld (oldstk),sp ;save stack
- ld (scrtch),bc ;first byte after pgm
- ld (high),de ;high memory
- ld (cmdlin),hl ;command line
- ld sp,stack ;new stack
- ;
- ; main parsing routine
- ; will respond to the following syntax :
- ; KERMIT {S,F=file,B=baud,P=par,W=word,C=channel}
- ; update {L=lrecl} 85.09.19
- ;
- iparse:
- ld e,0 ;init for first call nxtfld
- ld hl,(cmdlin) ;get command line
- ld c,(hl) ;maximum length to parse
- inc hl ;points to first byte
- i0:
- ld a,(hl) ;get first byte
- cp ' ' ;white space ?
- jr z,i1 ;yes, now find {
- dec c ;decrement length to parse
- inc hl ;update pointer
- ld a,c ;length in a
- cp 0 ;is it null ?
- jr nz,i0 ;no, go on
- jp go ;yes, no parse to be done
- i1:
- dec c ;decrement length to parse
- inc hl ;update pointer
- ld a,c ;get length in a
- cp 0 ;is it null ?
- jp z,go ;nothing to parse
- ld a,(hl) ;get byte in a
- cp ' ' ;is it another null ?
- jp z,i1 ;yes, get one more
- cp '{' ;is it valid start ?
- jp nz,seter ;no good
- dec c ;decrement length
- inc hl ;update pointer
- ld a,c ;get length in a
- cp 0 ;is it null ?
- jp z,seter ;no good
- parse:
- call nxtfld ;get next field
- jp nz,go ;go !
- ld a,b ;length of field
- cp 0 ;is it null ?
- jp z,seter ;disaster ...
- call handler ;work with this parameter
- ld a,c ;length left to parse
- or a ;is it null ?
- jp nz,parse ;no, do it again
- ld a,0FFH ;terminator ?
- cp d ;in register D
- jp z,seter ;yes and parse is incomplete
- jp go ;go !
- handler:
- ld a,(hl) ;get first caracter of field
- ld (byte),a ;in byte
- push hl ;save
- push bc
- jumptb parsetb,byte ;jump accordingly
- sets:
- pop bc
- pop hl
- ld a,11 ;open pseudo-state
- ld (state),a ;set send state
- ld a,'R' ;read only
- ld (paraml+6),a ;put fcb in read state
- ld a,0 ;do not create
- ld (paraml+9),a ;and do not create
- ret
- setr:
- pop bc
- pop hl
- ld a,3
- ld (state),a ;set receive state
- ret
- setf:
- pop bc
- pop hl
- call nxtfld ;get next field
- push hl ;save
- push de
- push bc
- push hl ;i will need it twice
- ld a,b ;get length in a
- cp 0 ;is it null ?
- jp z,f0 ;yes error
- cp 30 ;greater than 30
- jp nc,f0 ;yes, error
- ld de,fcb ;where filaname should be
- ld c,b ;with length in BC
- ld b,0
- ldir ;move from hl to de
- ex de,hl ;end of filnam in hl
- ld (hl),13 ;put in a CR
- ld (filnam),a ;get filename length in place
- ld de,filnam ;to filenam
- inc de ;plus one (first byte is len)
- pop hl ;from here
- ld c,a ;length in bc
- ld b,0
- ldir ;move from param list to filnam
- ex de,hl ;hl points to end
- ld (hl),13 ;put in a CR
- pop bc ;restore
- pop de
- pop hl
- ret
- f0:
- prmes e4 ;not valid filename
- jp abort ;end in disaster
- setp:
- pop bc
- pop hl
- call nxtfld ;get next field
- ld a,(hl) ;get first byte in a
- cp 'O' ;is it odd
- jr nz,p0 ;no ...
- ld (parity),a ;set in comm buffer
- ld (init),a ;init flag
- ret
- p0:
- cp 'E' ;is it even ?
- jr nz,p1 ;no ...
- ld (parity),a ;set in comm buffer
- ld (init),a ;init flag
- ret
- p1:
- cp 'N' ;is it none ?
- jr nz,p2 ;no, error
- ld (parity),a ;set in comm buffer
- ld (init),a ;init flag
- ret
- p2:
- prmes e5 ;invalid parity
- jp abort ;end in disaster
- setb:
- pop bc
- pop hl
- call nxtfld ;get next field
- push hl ;save
- push de
- push bc
- ex de,hl ;de=compare string
- ld hl,baudtb ;baud rate table
- ld a,49 ;svc scan
- rst 8 ;dos
- jr nz,b0 ;not found
- inc hl ;increment to code
- inc hl
- inc hl
- inc hl
- ld a,(hl) ;get code in a
- ld (baud),a ;in comm buffer
- ld (init),a ;init flag
- pop bc ;restore
- pop de
- pop hl
- ret
- b0:
- prmes e6 ;unsupported baud rate
- jp abort ;in disaster
- setw:
- pop bc
- pop hl
- call nxtfld ;get next field
- ld a,(hl) ;first byte in a
- cp '7' ;is it 7
- jr nz,w0 ;no, try 8
- sub '0' ;convert to binary
- ld (wdlen),a ;in comm buffer
- ld (init),a ;set init flag
- ret
- w0:
- cp '8' ;is it 8
- jr nz,w1 ;no, error
- ld (wdlen),a ;in comm buffer
- ld (init),a ;init flag
- ret
- w1:
- prmes e7 ;bad word length
- jp abort ;disaster
- setc:
- pop bc
- pop hl
- call nxtfld ;get next field
- ld a,(hl) ;first byte in a
- cp 'A' ;is it cnannel A ?
- jr nz,c0 ;no, try B
- ld (port),a ;in comm buffer
- ld (init),a ;init flag
- ret
- c0:
- cp 'B' ;is it B
- jr nz,c1 ;no, error
- ld (port),a ;in comm buffer
- ld (init),a ;init flag
- ret
- c1:
- prmes e8 ;invalid channel
- jp abort ;disaster
- seter:
- pop bc
- pop hl
- prmes e9 ;invalid parameter
- prmes u0 ;usage is...
- jp abort ;disaster
- setl:
- pop bc ;restore
- pop hl
- call nxtfld ;get record length
- push hl ;save
- push bc
- push de
- ld de,work ;to store value and padd
- ld a,b ;get length
- cp 6 ;maximum lebgth + 1
- jp nc,seter ;no good ... bye
- l0:
- cp 5 ;maximum length
- jr z,l1 ;finished moving
- inc a ;increase length
- inc de ;and pointer
- jr l0
- l1:
- ld c,b ;get length in bc
- ld b,0
- ldir ;move to work+(5-bc)
- ld hl,work ;get hl to point correctly
- ld b,1 ;code to convert to bin
- ld a,21 ;BINDEC svc
- rst 8 ;dos
- ld a,e ;get binary value
- ld (lrecl),a ;save in fcb
- pop de ;restore
- pop bc
- pop hl
- ret
- nxtfld:
- ld d,0 ;initialize de to e
- add hl,de ;add to hl - where to start
- ld de,lab ;list address block
- ld a,46 ;parse svc
- rst 8 ;dos
- ret
- go:
- call initcm ;initialize comm channel
- prmes 00 ;now say hello
- ; here is the main jump, every routine ends here
- ;
- mjump:
- jumptb stjump,state
- ;
- ;
- ;
- ; and this is the main receive file jump
- ;
- rfjump:
- jumptb rftab,rtype
- ;
- ; and the main receive data jump
- ;
- rdjump:
- jumptb rdtab,rtype
- ;
- end start
- <<< trsmssg.mac >>>
- subttl messages (because the assembler is too dumb)
- dseg
- ;
- ;
- ;mssg to reserve space for a message and it's length
- ; syntax mssg lab,<message>
- ; where lab is a maximum of four bytes
- ;
- mssg macro lab,mess
- .xlist ;do not list expansion
- public m_&lab,l_&lab
- m_&lab:
- db '&mess'
- l_&lab: db 0
- db $-m_&lab
- .list
- endm
- ;
- ; the message that should appear
- ;
- mssg 00,<Kermit (trsdos II, version 1.2)>
- mssg a0,<aborting due to fatal error>
- mssg u0,<KERMIT {(S,R),F=filename,B=baud,P=par,L=lrecl,C=channel}>
- mssg e0,<Kermit exit>
- mssg db0,<jumping from mjump>
- mssg db1,<jumping from rfjump>
- mssg db2,<jumping from rdjump>
- mssg db3,<entering receive-init>
- mssg db4,<entering receive-file>
- mssg db5,<entering receive-data>
- mssg db6,<entering rpack>
- mssg db7,<entering spack>
- mssg db8,<exiting timer call>
- mssg db9,<entering rp1>
- mssg db10,<entering rp2>
- mssg db11,<entering rp3>
- mssg db12,<entering rp4>
- mssg db13,<entering rp5>
- mssg db14,<entering rp6>
- mssg e3,<invalid word length>
- mssg e4,<invalid filename>
- mssg e5,<invalid parity>
- mssg e6,<unsupported baud rate>
- mssg e7,<invalid word length>
- mssg e8,<invalid channel>
- mssg e9,<invalid parameter>
- end
- <<< trsrecv.mac >>>
- title krecv/mac reception unit
- cseg
- ;
- ;
- extrn recptr,recbuf,rplus,mjump,rfjump,rdjump
- extrn spaket,rpaket,screen
- extrn rplus,sinit,state,byte,n,r
- extrn rpack,spack,abort,acsum,flush
- extrn fcb,writnx,open,rinit,close
- extrn lrecl
- public r_init,r_file,rf_b,rf_x,rf_f
- public r_data,rd_z,rd_d
- ;
- len equ 0
- seq equ 1
- type equ 2
- data equ 3
- quote equ '#'
- _a equ 1
- _c equ 2
- _r equ 3
- _rf equ 4
- _rd equ 5
- ;
- ;
- subttl macros used in this module
- ;
- ;prmes to display messages
- ;
- prmes macro lab
- .xlist
- extrn m_&lab,l_&lab
- push hl
- push bc
- ld hl,m_&lab
- ld bc,(l_&lab)
- ld c,13
- ld a,9
- rst 8
- pop bc
- pop hl
- .list
- endm
- ;movb
- ;
- movb macro value,loc
- .xlist
- push af
- ld a,value
- ld (loc),a
- pop af
- .list
- endm
- ;
- ;blmov
- ;
- blmov macro source,dest,len
- .xlist
- local $1,$2
- push hl
- push bc
- push de
- ld hl,source
- ld de,dest
- ld a,(len)
- cp 0
- jr nz,$1
- ld b,1
- ld c,0
- jp $2
- $1:
- ld b,0
- ld c,a
- $2:
- ldir
- pop de
- pop bc
- pop hl
- .list
- endm
- ;
- ;fack to format an ack paket
- ;
- f_ack macro
- .xlist
- ld (iy+len),3
- ld a,(n)
- add a,' '
- ld (iy+seq),a
- ld (iy+type),'Y'
- ld hl,spaket
- call acsum
- .list
- endm
- ;
- ;nplus
- ;
- nplus macro
- .xlist
- ld hl,n
- inc (hl)
- res 6,(hl) ;not over 63
- .list
- endm
- ;
- subttl receive initialize
- ;
- ; receive init
- ;
- r_init:
- movb 0,n ;set packet count to 0
- movb 0,r ;and retry count to 0
- ld ix,rpaket ;ix will always point there
- call flush ;flush comm port
- call rpack ;and get a packet
- jp c,rplus ;no good, nack, r+
- ld a,(ix+type) ;get packet type
- cp 'S' ;is it a send ?
- jp nz,abort ;nope, no good
- movb 10,byte ;will move 10 bytes
- blmov rpaket+data,sinit,byte
- ;to send init buffer
- ld hl,sinit+4 ;address of eol
- res 5,(hl) ;sub 32 to get real eol
- ;and prepare to ack
- ;with our parameters
- ld iy,spaket ;iy will always point there
- ld (iy+len),12 ;length
- ld (iy+type),'Y' ;ack
- ld a,(n) ;current packet number
- add a,32 ;make printable
- ld (iy+seq),a ;save in ack packet
- blmov rinit,spaket+data,byte
- ;all the info
- ld hl,spaket ;hl points to send packet
- call acsum ;add checksum
- call spack ;and pray it gets there
- nplus ;increment n
- movb 0,r ;set retry count to 0
- movb _rf,state ;to receive file
- jp mjump ;back
- subttl receive file
- page
- ;
- ; receive file
- ;
- r_file:
- call rpack ;get a packet
- jp c,rplus ;no good
- ld a,(n) ;packet number expected
- add a,' ' ;make printable
- cp (ix+seq) ;equal to received packet
- jp z,rfgood ;yes
- call spack ;re-ack, it was lost
- jp rplus ;increment r, nak
- rfgood:
- jp rfjump
- ;jump according to table
- rf_b:
- ;case(break)
- f_ack ;format ack
- call spack ;and send it
- nplus
- movb _c,state ;set state to complete
- jp mjump ;and back
- rf_x:
- ;case(type on screen)
- movb 1,screen ;set flag on
- movb _rd,state ;set state to receive data
- f_ack ;format ack
- call spack ;and send it
- nplus ;increment packet count
- jp mjump ;and back
- rf_f:
- ;case(file header)
- ld a,(ix+len) ;get lenght
- sub ' '+3 ;minus seq,type, chksum
- ld (ix+len),a ;store back
- blmov rpaket+data,fcb,rpaket
- ;move filename to fcb
- ld hl,fcb ;start of filename
- ld c,a ;length
- ld b,0 ;bc = length
- ld a,'.' ;to scan for dot
- cpir ;found dot
- dec hl ;adjust pointer
- ld (hl),'/' ;replace by '/'
- ld a,0 ;clr a
- cp c ;c = 0 ?
- jp z,r_f0 ;yes, put in cr
- ld hl,fcb ;first byte of filename
- ld a,(rpaket) ;length of filename
- add a,l ;add low byte to length
- ld l,a ;store back low byte
- ld a,0 ;clear a
- adc a,h ;add high byte to carry
- ld h,a ;put back in h
- r_f0: ld (hl),13 ;put in a carriage return
- call open ;and open file
- f_ack ;format an ack
- call spack ;and send it
- nplus ;increment packet count
- movb _rd,state ;set state to receive data
- jp mjump ;and back
- subttl receive data
- page
- ;
- ; receive data
- ;
- r_data:
- call rpack ;get a packet
- jp c,rplus ;no good
- ld a,(n) ;get expected packet count
- add a,' ' ;make printable
- cp (ix+seq) ;equal to received ?
- jp z,rdgood ;yes, all ok
- call spack ;re-ack, it was lost
- jp rplus ;update retry count
- rdgood:
- jp rdjump
- rd_z:
- ;case(end of file)
- call writnx ;flush buffer
- call close ;close file
- f_ack ;format an ack
- call spack ;and send it
- nplus ;increment packet count
- movb _rf,state ;set state to receive file
- jp mjump ;and back
- rd_d:
- ;case(data)
- ld hl,rpaket+data ;start of data
- ld a,(rpaket) ;total length
- sub ' '+3 ;convert to numeric
- cp 0 ;is it null ?
- jp z,rd_d2 ;yes, finish
- ld bc,(recptr) ;pointer inside recbuf
- ld b,0 ;turn off high byte
- push hl ;save temporarily
- ld hl,recbuf ;record address
- add hl,bc ;plus length
- ex de,hl ;pointer in de
- pop hl ;restore hl
- ;at this point :
- ; hl = rpaket
- ; de = inside recbuf
- ; a = length of packet
- rd_d1:
- push af ;save temporarily
- ld a,(hl) ;get current byte
- cp quote ;is it a quote ?
- jr nz,rd_d3 ;no, go on
- inc hl ;point to next byte
- pop af ;restore a
- dec a ;decrement counter
- push af ;and save again
- ld a,(hl) ;get next byte
- cp quote ;is it a quote ?
- jr z,rd_d3 ;yes, don't touch
- cp quote or 128 ;quote and eight bit
- jr z,rd_d3 ;yes don't touch either
- xor 64 ;uncontrollify
- ld (hl),a ;store back
- rd_d3: pop af ;restore
- ldi ;from rapket to recbuf
- dec a ;paket length minus one
- ld bc,(recptr) ;pointer inside recbuf
- inc c ;is incremented
- movb c,recptr ;and stored back
- push af ;save a
- ld a,(lrecl) ;get logical record length
- cp c ;compare to len(recbuf)
- jp nz,rd_d0 ;no, do not update yet
- call writnx ;write next record
- movb 0,recptr ;set pointer back to zero
- ld de,recbuf ;reset pointer to record buffer
- rd_d0:
- pop af ;restore a
- cp 0 ;is packet empty ?
- jp nz,rd_d1 ;no, get one more byte
- rd_d2:
- f_ack ;format an ack
- call spack ;and send it
- nplus ;update packet counter
- jp mjump ;and back
- end
- <<< trssend.mac >>>
- title ksend/mac sending unit
- cseg
- ;
- ;
- extrn recptr,recbuf,rplus,mjump
- extrn spaket,rpaket,screen
- extrn rplus,sinit,state,byte,n,r
- extrn rpack,spack,abort,acsum,flush
- extrn fcb,writnx,open,rinit,close
- extrn lrecl,readnx,buffil,filnam,tstack
- public s_init,s_file,s_open,s_break
- public s_data,s_eof
- ;
- len equ 0
- seq equ 1
- type equ 2
- data equ 3
- quote equ '#'
- _a equ 1
- _c equ 2
- _r equ 3
- _rf equ 4
- _rd equ 5
- _s equ 6
- _sf equ 7
- _sd equ 8
- _se equ 9
- _sb equ 10
- _o equ 11
- ;
- ;
- subttl macros used in this module
- ;
- ;prmes to display messages
- ;
- prmes macro lab
- .xlist
- extrn m_&lab,l_&lab
- push hl
- push bc
- ld hl,m_&lab
- ld bc,(l_&lab)
- ld c,13
- ld a,9
- rst 8
- pop bc
- pop hl
- .list
- endm
- ;movb
- ;
- movb macro value,loc
- .xlist
- push af
- ld a,value
- ld (loc),a
- pop af
- .list
- endm
- ;
- ;blmov
- ;
- blmov macro source,dest,len
- .xlist
- local $1,$2
- push hl
- push bc
- push de
- ld hl,source
- ld de,dest
- ld a,(len)
- cp 0
- jr nz,$1
- ld b,1
- ld c,0
- jp $2
- $1:
- ld b,0
- ld c,a
- $2:
- ldir
- pop de
- pop bc
- pop hl
- .list
- endm
- ;
- ;fack to format an ack paket
- ;
- f_ack macro
- .xlist
- ld (iy+len),3
- ld a,(n)
- add a,' '
- ld (iy+seq),a
- ld (iy+type),'Y'
- ld hl,spaket
- call acsum
- .list
- endm
- ;
- ;nplus
- ;
- nplus macro
- .xlist
- ld hl,n
- inc (hl)
- res 6,(hl)
- movb 0,r
- .list
- endm
- ;
- subttl open file (pseudo-state, precedes send_init)
- page
- ;
- ; open file
- ;
- s_open:
- call open ;open file (assume fcb set)
- movb _s,state ;state = send_init
- movb 0,n ;packet number to 0
- movb 0,r ;reset retry count
- call flush ;clear comm buffers
- jp mjump ;and back
- subttl send initialisation routine
- page
- ;
- ; send init parameters
- ;
- s_init:
- ld ix,rpaket
- ld iy,spaket
- ld (iy+len),12 ;length of init packet
- ld (iy+type),'S' ;type send init
- ld a,(n) ;current packet number
- add a,' ' ;make printable
- ld (iy+seq),a ;into packet
- movb 12,byte ;number of bytes to move
- blmov rinit,spaket+data,byte
- ld hl,spaket ;to point correctly
- call acsum ;compute checksum
- call spack ;and send packet
- ld a,(hl) ;get paket length and fix it
- sub ' ' ;because there might be a retry
- ld (hl),a ;save back
- call rpack ;get answer
- jp c,rplus ;no good
- call tstack ;was it a good ack ?
- jp c,rplus ;no, send it again
- blmov rpaket+data,sinit,byte
- ;move parameters to keep
- ld hl,sinit+4 ;address of eol
- res 5,(hl) ;sub 32 to get real eol
- ld hl,sinit ;maxlen to send
- res 5,(hl) ;sub 32
- nplus ;increment packet count
- movb _sf,state ;state = send file header
- jp mjump ;and back
- subttl send file header information
- page
- ;
- ; send file header
- ;
- s_file:
- ld hl,filnam+1 ;where the filame start
- ld a,(filnam) ;it's length
- ld b,a ;store len in b
- ld a,'/' ;byte to look for
- s1:
- cp (hl) ;is this a '/' ?
- jp z,s2 ;yes change it t '.'
- inc hl ;advance pointer
- djnz s1 ;and check next byte
- jp s3 ;there was no '/'
- s2:
- ld a,'.' ;a dot to normalize filename
- ld (hl),a ;in place
- s3:
- ld (iy+type),'F' ;of type file header
- ld a,(n) ;get packet count
- add a,' ' ;make printable
- ld (iy+seq),a ;insert in spacket
- blmov filnam+1,spaket+data,filnam
- ;put in filename
- ld a,(filnam) ;get filename length
- add a,3 ;add len,seq,type
- ld (iy+len),a ;set in spacket
- ld hl,spaket ;hl to point correctly
- call acsum ;compute checksum
- call spack ;send it
- ld a,(hl) ;get paket length and fix it
- sub ' ' ;because there might be a retry
- ld (hl),a ;save back in spaket
- call rpack ;get answer
- jp c,rplus ;no good
- call tstack ;was it a good ack ?
- jp c,rplus ;no
- nplus ;update packet count
-
- call buffil ;get a bufferfull
- jp c,s_eof ;it was the end of file
- movb _sd,state ;state = send_data
- jp mjump ;return
- subttl send data from file
- page
- ;
- ; send data
- ;
- s_data:
- ld (iy+type),'D' ;data packet
- ld a,(n) ;packet number
- add a,' ' ;make printable
- ld (iy+seq),a ;into packet
- ld hl,spaket ;hl point correctly
- call acsum ;compute checksum
- call spack ;send it
- ld a,(hl) ;get length to fix it in case
- sub ' ' ; of a bad ack
- ld (hl),a ;save back in spaket
- call rpack ;get answer
- jp c,rplus ;no good
- call tstack ;a good ack ?
- jp c,rplus ;nope...
- nplus ;yes, update packet count
- call buffil ;get next packet ready
- jp c,s_eof ;we reach the eof
- jp mjump ;and back
- subttl send end of file
- page
- ;
- ; send end of file
- ;
- s_eof:
- movb _se,state ;might not be done
- ld (iy+type),'Z' ;eof in spacket
- ld (iy+len),3 ;length
- ld a,(n) ;packet number
- add a,' ' ;make printable
- ld (iy+seq),a ;into packet
- ld hl,spaket ;to point correctly
- call acsum ;compute checksum
- call spack ;send packet
- ld a,(hl) ;get paket length
- sub ' ' ;and fix it
- ld (hl),a ;back in spaket
- call rpack ;get answer
- jp c,rplus ;no good
- call tstack ;test for good ack
- jp c,rplus ;no good
- nplus ;good, update packet count
- movb _sb,state ;state = break transmission
- jp mjump ;and back
- subttl send break transmission
- page
- ;
- ; send break transmission
- ;
- s_break:
- ld (iy+type),'B' ;in spaket, set type
- ld (iy+len),3 ;and length
- ld a,(n) ;current packet number
- add a,' ' ;make printable
- ld (iy+seq),a ;store in spaket
- ld hl,spaket ;hl to point correctly
- call acsum ;compute checksum
- call spack ;send packet
- ld a,(hl) ;get paket length and fix it
- sub ' ' ;there might be a retry
- ld (hl),a ;save back in spaket
- call rpack ;get answer
- jp c,rplus ;no good
- call tstack ;check if correct ack
- jp c,rplus ;no, send again
- movb _c,state ;complete
- jp mjump ;FIN...
- end
- <<< trsutil.mac >>>
- subttl kutil/mac utilities and other odd routines
- extrn rlen,slen,csvc,rsvc,ssvc,r,n,mjump
- extrn spaket,rpaket,byte,recptr,sinit
- extrn fcb,lrecl,filbuf,recbuf,lrecl,paraml
- public flush,rplus,abort,exit,acsum,spack
- public open,close,writnx,readnx,kill
- public rpack,initcm
- extrn init,port,altsvc,nsvc
- ;
- ; useful symbole
- ;
- soh equ 1
- tout equ 10
- len equ 0
- seq equ 1
- type equ 2
- data equ 3
- dfport equ 'A'
- ;
- ;
- ;timer to interrupt a given routine after a number of seconds
- ; syntax timer routin,seconds
- ; where routin is the interrupt handler
- ;
- timer macro routin,second
- push hl
- push bc
- ld hl,routin ;routine to jump to
- ld bc,second ;number of seconds
- svc 25 ;timer call
- pop bc
- pop hl
- endm
- ;
- ;svc to make a trsdos supervisor call
- ; syntax svc code
- ; where code is the trsdos code
- ;
- svc macro code
- ld a,code
- rst 8
- endm
- ;
- ;
- ;prmes to print messages on the screen
- ; syntax prmes lab
- ; where lab if the label as defined with mssg
- ;
- prmes macro lab
- .xlist
- extrn m_&lab,l_&lab
- push hl
- push bc
- ld hl,m_&lab ;get address of message
- ld bc,(l_&lab) ;and length
- ld c,13 ;add a CR at end of ttyout
- svc 9 ;call dos
- pop bc
- pop hl
- .list
- endm
- ;
- ;blmov to move a block of text
- ; syntax blmov source,destination,length
- ; if length is 0 then assume 256
- ;
- blmov macro source,dest,len
- .xlist
- local $1,$2
- push hl
- push bc
- push de
- ld hl,source ;address of source
- ld de,dest ;address of destination
- ld a,(len) ;get length
- cp 0 ;is it zero ?
- jr nz,$1
- ld b,1 ;then set bc = 256
- ld c,0 ;(b=1 ; c=0)
- jp $2 ;go to start move
- $1:
- ld b,0
- ld c,a ;bc = length
- $2:
- ldir ;move and check if bc=0
- pop de
- pop bc
- pop hl
- .list
- endm
- ;
- ;readnx to read next record sequentially
- ; Returs with the record in recbuf
- ; And, at eof, will jump to sendeof
- ; (This macro will not save redisters)
- ;
- readnx:
- ld de,fcb ;file control block
- svc 34 ;read next svc
- jp nz,abort ;bad read, abort
- ld a,(lrecl) ;get logacal record length
- cp 0 ;is it 256 ?
- jp nz,read0 ;no, all is ok
- blmov filbuf,recbuf,lrecl ;move to recbuf
- read0:
- ret
- ;
- ;open open a file according to fcb and paramlist
- ;
- open:
- push hl
- push de
- ld de,fcb ;file control block
- ld hl,paraml ;parameter list
- svc 40 ;open call
- jp nz,abort ;file not found
- ;or file cannot create
- pop de
- pop hl
- ret
- ;
- ;kill kill a file using current fcb
- ;
- kill:
- push de
- ld de,fcb ;file control block
- svc 41 ;kill call
- jp nz,abort ;no good (password ?)
- pop de
- ret
- ;
- ;close file using current fcb
- ;
- close:
- push de
- ld de,fcb
- svc 42
- jp nz,abort
- xor a ;clr a
- ld (recptr),a ;reset pointer to 0
- pop de
- ret
- ;
- ;writnx write next sequential record
- ;
- writnx:
- ld a,(lrecl) ;get logical record length
- cp 0 ;is it 256 ?
- jp nz,writ0 ;no, go on
- blmov recbuf,filbuf,lrecl ;get to filbuf
- writ0:
- push de
- ld de,fcb ;file control block
- svc 43 ;write call
- jp nz,abort ;no good
- pop de
- ret
- ;
- ;delay in seconds
- ;
- delay macro sec
- .xlist
- local $1
- push bc
- ld bc,0 ;set for 426 milisecs
- push hl
- ld l,sec ;number of seconds
- $1:
- svc 6 ;call for delay
- svc 6 ;2 * 426 milisecs = 1 s.
- dec l ;sec--
- xor a ;a = 0
- cp l ;sec = 0 ?
- jr nz,$1 ;no, play it again sam
- pop hl
- pop de
- .list
- endm
- ;
- ;jumptb jump according to a given table and a one byte code
- ;
- ; syntax jumptb table,code
- ;
- jumptb macro table,code
- .xlist
- local $1
- ld hl,table ;get jump table address
- ld bc,(code) ;and code (note that c is messed up)
- ld a,c
- ld b,a
- svc 28 ;lookup call
- jr z,$1 ;found
- ld hl,table+1 ;get abort address
- $1:
- jp (hl) ;bye ...
- .list
- endm
- ;
- ;initcm initalise comm channel A or B
- ; and set up correct svc communication calls
- ;
- initcm:
- ld a,(init) ;get initial code
- cp 0 ;should we init ?
- jr z,i1 ;no, go set up svc
- ;
- ld hl,port ;get port paramlist
- ld b,0 ;turn off port
- svc 55 ;dos call
- ld b,1 ;turn on
- svc 55 ;dos call
- i1:
- ld a,(port) ;get channel A or B
- cp dfport ;is this default ?
- jr z,i2 ;yes, all ok
- blmov altsvc,init,nsvc;set up alternate svc's
- i2:
- ret
- ;
- ;xmitb transmit a byte that is pointed to by hl
- ;
- xmitb macro
- .xlist
- local $1
- $1:
- ld a,(ssvc) ;get transmit svc
- ld b,(hl) ;and byte to transmit
- rst 8 ;dos call
- jr nz,$1 ;assume busy, try again
- .list
- endm
- ;
- ;rcvb receive byte and return it in a
- ;
- rcvb macro
- .xlist
- local $1
- push bc
- $1:
- ld a,(rsvc) ;get receive svc
- rst 8 ;dos call
- jr nz,$1 ;try it again
- ld a,b ;store (might not be good)
- pop bc
- .list
- endm
-
- ;
- ;nplus to increment the packet number count
- ;
- nplus macro
- ld hl,n
- inc (hl)
- endm
- ;
- ;dec3 decrement three times a register or register pair
- ;
- dec3 macro reg
- dec reg
- dec reg
- dec reg
- endm
- ;
- ;addbc to add a to bc in checksum computation
- ;
- addbc macro
- .xlist
- add a,c ;c=c+1 (there might be a carry)
- ld c,a ;back in c
- ld a,0 ;not xor a because we need the carry
- adc a,b ;add the carry to b
- ld b,a ;back in b
- .list
- endm ;bc=bc+a
- ;
- ;f_ack to format ack using current n
- ;
- f_ack macro
- .xlist
- ld (iy+len),3 ;length=3
- ld a,(n) ;current packet count
- add a,' ' ;make printable
- ld (iy+seq),a ;put n in packet
- ld (iy+type),'Y' ;type = ack
- ld hl,spaket ;hl points to send packet
- call acsum ;and add the checksum
- .list
- endm
- ;
- ;movb to move a byte to memory
- ;
- movb macro value,loc
- .xlist
- push af ;save
- ld a,value ;get byte
- ld (loc),a ;save
- pop af ;restore
- .list
- endm
- subttl rpack - receive packet routine
- page
- ;
- ; rpack receive packet routine
- ; call rpack
- ; will discard soh on reception
- ; and will return with carry set
- ; if timout occured or cheksum wrong
- ;
- rpack:
- timer rp0,tout ;set timer handler
- rp1:
- ld hl,rpaket ;set up hl
- rcvb ;get a byte
- cp soh ;is it a soh ?
- jr nz,rp1 ;no, not yet, start over
- ld b,0 ;for checksum bc=0
- ld c,0 ;*****************
- rp2: ;len
- rcvb ;get a byte
- cp soh ;is it a soh ?
- jp z,rp1 ;yes, re-sync
- ld (hl),a ;save in rpaket
- addbc ;add to bc for checksum
- ld a,(hl) ;get back byte
- inc hl ;point to next byte
- sub ' '+3 ;convert to numeric
- ld (rlen),a ;and save
- rp3: ;packet number
- rcvb ;get a byte
- cp soh ;soh ?
- jp z,rp1 ;yes, re-sync
- ld (hl),a ;save in rpaket
- inc hl ;update counter
- addbc ;add to bc for checksum
- rp4: ;type of packet
- rcvb ;get a byte
- cp soh ;soh ?
- jp z,rp1 ;yes, re-sync
- ld (hl),a ;save in rapket
- inc hl ;update pointer
- addbc ;add to bc for checksum
- ld a,(rlen) ;get data length
- cp 0 ;is it null ?
- jp z,rp6 ;yes, get checksum now
- rp5: ;data field
- rcvb ;get a byte
- cp soh ;soh ?
- jp z,rp1 ;yes, re-sync
- ld (hl),a ;save
- inc hl ;update counter
- addbc ;add to bc for checksum
- ld a,(rlen) ;get length of packet
- dec a ;decrement
- ld (rlen),a ;ans store back
- cp 0 ;is it null ?
- jp nz,rp5 ;no, get one more byte
- rp6: ;checksum
- rcvb ;get a byte
- cp soh ;soh ???
- jp z,rp1 ;yes, re-sync
- sub ' ' ;convert to numeric
- ld (byte),a ;save received checksum
- ld a,c ;get low byte
- and 300O ;only two high bits
- rlca ;rotale left
- rlca ;twice
- add a,c ;add back to low byte
- and 077O ;only six bits
- ld c,a ;computed checksum
- ld a,(byte) ;received checksum
- cp c ;equal ?
- jp nz,rp0 ;no good
- timer 0,0 ;terminate timout handler
- scf ;ser carry to 1
- ccf ;back to 0
- ret ;and return
- rp0: timer 0,0 ;terminate timout handler
- scf ;set carry flag
- ret
- ;
- ;
- subttl flush - to reset communication port
- page
- ;
- ; flush to reset internal communication buffer
- ; (mostly to get rid of stacked up naks)
- flush:
- push bc ;save
- ld b,6 ;code to reset buffer
- ld a,(csvc) ;control svc
- rst 8 ;dos call
- pop bc ;restore
- ret
- ;
- subttl rplus - to increment retry count
- page
- ; rplus increment retry count and jump back
- ;
- rplus:
- ld a,(r) ;get retry count
- inc a ;increment it
- cp tout ;to maximum ?
- jp z,abort ;yes abort
- ld (r),a ;save back
- jp mjump ;and go back
- ;
- subttl abort - end in disaster sending an error packet
- page
- ; abort end transmission and die...
- ;
- abort:
- prmes a0 ;aborting ...
- ld (iy+len),3 ;length = 3
- ld a,(n) ;get current packet seq
- cp 0 ;are we at beginning ?
- jp z,ab0 ;yes, do not send error pak
- add a,' ' ;make printable
- ld (iy+seq),a ;and store
- ld (iy+type),'E' ;type error packet
- ld hl,spaket ;set up hl
- call acsum ;compute checksum
- call spack ;and send packet
- ab0:
- exit: prmes e0 ;end of job
- rst 0 ;bye !
- ;
- subttl acsum - add checksum to a packet
- page
- ; acsum compute and store checksum (hl)
- ;
- acsum:
- push hl ;save
- push bc ;save
- ld b,0 ;initialize bc to 0
- ld c,0 ;******************
- ld a,(hl) ;get length
- ld (slen),a ;save it
- add a,' ' ;make printable
- ld (hl),a ;store back in packet
- ac0:
- ld a,(hl) ;get a byte
- addbc ;add to bc for checksum
- inc hl ;increment pointer
- ld a,(slen) ;get length
- dec a ;decrement it
- ld (slen),a ;save it back
- cp 0 ;are we at end ?
- jp nz,ac0 ;no, get one more byte
- ld a,c ;get low byte of sum
- and 300O ;only 2 high bits
- rlca ;rotate left
- rlca ;twice
- add a,c ;add it back to low byte
- and 077O ;mask off 2 high bits
- add a,' ' ;and make pintable
- ld (hl),a ;store in packet
- pop bc ;restore
- pop hl ;restore
- ret
- ;
- subttl spack - send a packet already formatted
- page
- ; spack send a packet already formatted
- ;
- spack:
- push hl ;save
- ld a,(spaket) ;get length
- sub 31 ;real length
- ld (slen),a ;save it
- movb soh,byte ;store a soh
- ld hl,byte ;set up hl
- xmitb ;transmit (hl)=soh
- ld hl,spaket ;packet address
- ld a,(slen) ;and length
- sp1:
- push af ;save
- xmitb ;transmit (hl)
- pop af ;restore a
- dec a ;decrement length of packet
- inc hl ;update pointer
- cp 0 ;are we at end ?
- jp nz,sp1 ;no, one more byte
- ;now send eol
- ld hl,sinit+4 ;where eol is stored
- xmitb ;send it
- pop hl ;restore
- ret
- ;
- ;
- end
-
- <<< trsutil2.mac >>>
- subttl kutil2/mac utilities and other odd routines
- extrn rlen,slen,csvc,rsvc,ssvc,r,n,mjump
- extrn spaket,rpaket,byte,recptr,sinit
- extrn fcb,lrecl,filbuf,recbuf,lrecl,paraml
- extrn readnx,crp,cbp,word
- public tstack,buffil,eof
- ;
- ; useful symbols
- ;
- soh equ 1
- tout equ 10
- len equ 0
- seq equ 1
- type equ 2
- data equ 3
- dfport equ 'A'
- ;
- ;
- ;
- ;svc to make a trsdos supervisor call
- ; syntax svc code
- ; where code is the trsdos code
- ;
- svc macro code
- ld a,code
- rst 8
- endm
- ;
- ;
- ;prmes to print messages on the screen
- ; syntax prmes lab
- ; where lab if the label as defined with mssg
- ;
- prmes macro lab
- .xlist
- extrn m_&lab,l_&lab
- push hl
- push bc
- ld hl,m_&lab ;get address of message
- ld bc,(l_&lab) ;and length
- ld c,13 ;add a CR at end of ttyout
- svc 9 ;call dos
- pop bc
- pop hl
- .list
- endm
- ;
- ;blmov to move a block of text
- ; syntax blmov source,destination,length
- ; if length is 0 then assume 256
- ;
- blmov macro source,dest,len
- .xlist
- local $1,$2
- push hl
- push bc
- push de
- ld hl,source ;address of source
- ld de,dest ;address of destination
- ld a,(len) ;get length
- cp 0 ;is it zero ?
- jr nz,$1
- ld b,1 ;then set bc = 256
- ld c,0 ;(b=1 ; c=0)
- jp $2 ;go to start move
- $1:
- ld b,0
- ld c,a ;bc = length
- $2:
- ldir ;move and check if bc=0
- pop de
- pop bc
- pop hl
- .list
- endm
- movb macro value,loc
- .xlist
- push af
- ld a,value
- ld (loc),a
- pop af
- .list
- endm
- ;
- ;
- ; tstack to test a received packet for a good ack
- ;
- tstack:
- ld a,(n) ;cirrent packet count
- add a,' ' ;make printable
- cp (ix+seq) ;equal to seq received ?
- jp nz,plus1 ;no, test n+1
- ld a,(ix+type) ;get packet type
- cp 'Y' ;is an ack ?
- jp nz,nogood ;no return error code
- $1:
- scf
- ccf
- ret ;return no error
- plus1:
- inc a ;increment packet count
- cp (ix+seq) ;equal to received ?
- jp z,$1 ;yes, all ok
- nogood:
- scf ;set carry
- ret
- ;
- ; buffil to fill a send packet data field from
- ; record buffer
- ;
- buffil:
- movb 3,cbp ;initialize buffer pointer
- b5:
- ld a,(cbp) ;get buffer pointer
- inc a ;it might be one less
- ld hl,sinit ;maxlen to send
- cp (hl) ;equal to max or max-1 ?
- jp c,b0 ;no, there is room
- b4:
- ld a,(cbp) ;buffer pointer
- ld (iy+len),a ;in packet
- scf
- ccf
- ret ;return all ok
- b0:
- xor a ;clear a
- ld hl,crp ;record pointer address
- cp (hl) ;buffer empty ?
- jp nz,b1 ;no
- call readnx ;get something (EOF...)
- jp nc,b1 ;not end of file yet
- ld a,(cbp) ;spaket pointer
- ld (iy+len),a ;put in place
- cp 3 ;is this the start ?
- jp nz,b13 ;not yet, return normally
- scf ;flag to never return here
- b13: ret
- b1:
- ld a,(cbp) ;buffer pointer
- ld b,a ;save in b
- ld a,(sinit) ;maxlen to send
- sub b ;a=SA=mxl-cbp
- ld (byte),a ;save in byte
- ld a,(crp) ;record pointer
- ld b,a ;save in b
- ld a,(lrecl) ;record length
- sub b ;a=BA=lrecl-crp
- ld hl,byte ;get byte address
- cp (hl) ;BA > SA ?
- jp nc,b2 ;go move SA bytes
- ld (byte),a ;save BA in byte
- b2:
- ld hl,spaket ;packet address
- ld a,(cbp) ;current pointer
- add a,l ;add to low byte
- ld l,a ;save back
- ld a,0 ;clear a keeping carry
- adc a,h ;add carry to high byte
- ld h,a ;save back
- ex de,hl ;save in DE
- ld hl,recbuf ;record address
- ld a,(crp) ;record pointer
- add a,l ;add to low byte
- ld l,a ;save back
- ld a,0 ;clear a keeping carry
- adc a,h ;add to high byte
- ld h,a ;save back
- ;
- ; here we move from recbuf to spaket
- ; making sure the control caracters are quoted,
- ; and uncontrollified (same thing for del),
- ; and that the quote caracter is itself quoted.
- ;
- movb 0,word ;this will be the count from recbuf
- movb 0,word+1 ;and the count of quote bytes
- b9:
- ld a,31 ;limit of control char.
- ld b,(hl) ;get character in b to
- res 7,b ; reset seventh bit
- cp b ;compare 31 to byte to send
- jp c,b6 ;this is not a control char.
- b8:
- ld a,(sinit+5) ;get the quote byte
- ld (de),a ;move in spaket
- inc de ;update spaket pointer
- push hl ;save
- ld hl,word+1 ;points to quote count
- inc (hl) ;update count
- pop hl ;restore
- ld a,64 ;to uncontrollify
- xor (hl) ;the byte to send
- ld (hl),a ;and put it back in recbuf
- jp b7 ;go send it
- b6:
- ld a,127 ;del byte
- cp b ;is this it ?
- jp z,b8 ;yes go uncontrollify it
- ;
- ld a,(sinit+5) ;quote byte
- cp (hl) ;is this what we are sending ?
- jp nz,b7 ;no, go on
- ld (de),a ;yes put it in spaket
- inc de ;and update pointer
- push hl ;save
- ld hl,word+1 ;get quote count address
- inc (hl) ;and update it
- pop hl ;restore hl
- b7:
- ldi ;move the byte in spaket
- push hl ;save
- ld hl,word ;count address
- inc (hl) ;update it
- ld a,(hl) ;get count of bytes from recbuf
- ld hl,word+1 ;and count of quote bytes
- add a,(hl) ;add them to get real count
- ld hl,byte ;address of max to moved
- inc a ;increment real count
- ; to get to max-1 or max
- cp (hl) ;compare count+1 to max
- jp nc,b10 ;this is it, finish.
- pop hl ;restore
- jp b9 ;one more time...
- b10:
- ld a,(word) ;real count moved from recbuf
- ld (byte),a ;put where we need it
- pop hl ;restore to recbuf
- b11:
- ;
- ; at this point we have moved up to (byte) bytes
- ; maby less if there was only one control character
- ; Most of those bytes come from recbuf plus some
- ; instances of the quote byte.
- ;
- ld a,(word) ;number of bytes moved
- ld hl,word+1 ;address of quote count
- add a,(hl) ;a = total count
- ld hl,cbp ;buffer pointer
- add a,(hl) ;increment
- ld (hl),a ;save back in cbp
- ld hl,crp ;record pointer
- ld a,(word) ;get back bytes moved from rec
- add a,(hl) ;fix pointer
- ld (hl),a ;save back in cbp
- ld a,(lrecl) ;record length
- cp (hl) ;equal to record pointer ?
- jp nz,b3 ;no, go on
- movb 0,crp ;yes, reset crp
- b3:
- jp b5 ;one more time
- ;
- ; eof this routine will be accessed automatically
- ; from a read of eof by trsdos.
- ; Might be accessed twice ...
- ;
- eof:
- scf ;set carry
- ret
- end
-